/*
	Copyright (C) 2011 Daniel C. Dennison (dandennison84@gmail.com).  All rights reserved.
	This file is licensed under the EPL 1.0 (Eclipse Public License 1.0)
	A copy of the license can be found at http://www.eclipse.org/legal/epl-v10.html
*/

package com.gmail.dandennison84.accounting

class ChartOfAccountsHelper {
	private void configureAssetGroup(ChartOfAccountsBuilder coab) {
		coab.groups(accountType:AccountType.ASSETS, balanceType:BalanceType.DEBIT, closingType:ClosingType.PERMANENT,
			cashFlowStatementType:CashFlowStatementType.OPERATING_ACTIVITIES) {
			currentAssets {
				account(name:'Cash', cashFlowStatementType:CashFlowStatementType.CASH_ACCOUNT)
				account(name:'Investments', cashFlowStatementType:CashFlowStatementType.INVESTING_ACTIVITIES)
				account(name:'Accounts Receivable') {
					contra {
						name 'Allowance for doubtful accounts'
						balanceType BalanceType.CREDIT
						closingType ClosingType.TEMPORARY
					}
				}
				account(name:'Inventory')
				account(name:'Prepaid Expenses')
			}
			fixedAssets(cashFlowStatementType:CashFlowStatementType.INVESTING_ACTIVITIES) {
				account(name:'Equipment', contraName:'Equipment - Accumulated Depreciation')
				contra {
					name 'Equipment - Accumulated Depreciation'
					closingType ClosingType.TEMPORARY
					balanceType BalanceType.CREDIT
				}
				account(name:'Vehicles', contraName:'Vehicles - Accumulated Depreciation')
				contra {
					name 'Vehicles - Accumulated Depreciation'
					closingType ClosingType.TEMPORARY
					balanceType BalanceType.CREDIT
				}
				account(name:'Buildings', contraName:'Buildings - Accumulated Depreciation')
				contra {
					name 'Buildings - Accumulated Depreciation'
					closingType ClosingType.TEMPORARY
					balanceType BalanceType.CREDIT
				}

				account(name:'Land')

			}
		}
	}

	private configureLiabilitiesGroup(ChartOfAccountsBuilder coab) {
		coab.groups(accountType:AccountType.LIABILITIES, balanceType:BalanceType.CREDIT, closingType:ClosingType.PERMANENT,
			cashFlowStatementType:CashFlowStatementType.OPERATING_ACTIVITIES) {
			currentLiabilities {
				account(name:'Accounts Payable')
				account(name:'Accrued Expenses')
				account(name:'Wages Payable')
				account(name:'Taxes Payable')
				account(name:'Current Portion of Long-term Debt', cashFlowStatementType:CashFlowStatementType.FINANCING_ACTIVITIES)
				account(name:'Deposits from Customers')
			}
			longTermLiabilities(cashFlowStatementType:CashFlowStatementType.FINANCING_ACTIVITIES) {
				account(name:'Notes Payable')
			}
		}
	}

	private configureEquityGroup(ChartOfAccountsBuilder coab) {
		coab.groups(accountType:AccountType.EQUITY, balanceType:BalanceType.CREDIT, closingType:ClosingType.PERMANENT,
			cashFlowStatementType:CashFlowStatementType.FINANCING_ACTIVITIES) {
			account(name:'Common Stock')
			account(name:'Capital in Excess of Par')
			account(name:'Retained Earnings')
		}
	}

	private configureRevenueGroup(ChartOfAccountsBuilder coab) {
		coab.groups(accountType:AccountType.REVENUE, balanceType:BalanceType.CREDIT, closingType:ClosingType.TEMPORARY,
			cashFlowStatementType:CashFlowStatementType.OPERATING_ACTIVITIES) {
			operatingRevenue {
				account(name:'Freight Revenues')
				account(name:'Other Revenues', contraName:'Cost of Sales')
				contra(name:'Cost of Sales', balanceType:BalanceType.DEBIT)
			}
			nonOperatingRevenue {
				account(name:'Interest Income')
			}
		}
	}

	private configureExpensesGroup(ChartOfAccountsBuilder coab) {
		coab.groups(accountType:AccountType.EXPENSES, balanceType:BalanceType.DEBIT, closingType:ClosingType.TEMPORARY,
			cashFlowStatementType:CashFlowStatementType.OPERATING_ACTIVITIES) {
			operatingExpenses {
				account(name:'Wages')
				account(name:'Fuel')
				account(name:'Purchased Services and Materials')
				account(name:'Depreciation Expense')
				account(name:'Advertising Expense')
				account(name:'Other Expenses')
			}
			nonOperatingExpenses {
				account(name:'Interest Expense')
			}
			taxExpenses {
				account(name:'Tax Expense')
			}
		}
	}

	List<Account> getChartOfAccounts() {
		ChartOfAccountsBuilder coab = new ChartOfAccountsBuilder()
		configureAssetGroup(coab)
		configureLiabilitiesGroup(coab)
		configureEquityGroup(coab)
		configureRevenueGroup(coab)
		configureExpensesGroup(coab)
		coab.accounts
	}


}
